<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>ChaosBlade 批量管理平台</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: 'Microsoft YaHei', Arial, sans-serif;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            min-height: 100vh;
            padding: 20px;
        }

        .container {
            max-width: 1400px;
            margin: 0 auto;
            background: white;
            border-radius: 20px;
            box-shadow: 0 20px 60px rgba(0,0,0,0.3);
            overflow: hidden;
        }

        .header {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
            padding: 30px;
            text-align: center;
        }

        .header h1 {
            font-size: 2.5em;
            margin-bottom: 10px;
        }

        .header p {
            opacity: 0.9;
            font-size: 1.1em;
        }

        .content {
            padding: 30px;
        }

        .panel {
            background: #f8f9fa;
            border-radius: 10px;
            padding: 20px;
            margin-bottom: 20px;
        }

        .panel h2 {
            color: #667eea;
            margin-bottom: 20px;
            font-size: 1.5em;
        }

        .btn-group {
            display: flex;
            gap: 15px;
            flex-wrap: wrap;
            margin-bottom: 20px;
        }

        .btn {
            padding: 12px 24px;
            border: none;
            border-radius: 8px;
            font-size: 16px;
            cursor: pointer;
            transition: all 0.3s;
            font-weight: bold;
        }

        .btn-primary {
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            color: white;
        }

        .btn-primary:hover {
            transform: translateY(-2px);
            box-shadow: 0 5px 15px rgba(102, 126, 234, 0.4);
        }

        .btn-success {
            background: #28a745;
            color: white;
        }

        .btn-danger {
            background: #dc3545;
            color: white;
        }

        .btn-info {
            background: #17a2b8;
            color: white;
        }

        .btn:hover {
            transform: translateY(-2px);
            box-shadow: 0 5px 15px rgba(0,0,0,0.2);
        }

        .input-group {
            margin-bottom: 15px;
        }

        .input-group label {
            display: block;
            margin-bottom: 5px;
            color: #555;
            font-weight: bold;
        }

        .input-group input, .input-group select {
            width: 100%;
            padding: 10px;
            border: 2px solid #ddd;
            border-radius: 5px;
            font-size: 14px;
        }

        .input-group input:focus, .input-group select:focus {
            outline: none;
            border-color: #667eea;
        }

        .scenario-grid {
            display: grid;
            grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));
            gap: 20px;
            margin-top: 20px;
        }

        .scenario-card {
            background: white;
            padding: 20px;
            border-radius: 10px;
            border: 2px solid #e0e0e0;
            transition: all 0.3s;
        }

        .scenario-card:hover {
            border-color: #667eea;
            transform: translateY(-5px);
            box-shadow: 0 5px 15px rgba(102, 126, 234, 0.2);
        }

        .scenario-card h3 {
            color: #667eea;
            margin-bottom: 15px;
        }

        .log-output {
            background: #1e1e1e;
            color: #00ff00;
            padding: 20px;
            border-radius: 10px;
            font-family: 'Courier New', monospace;
            max-height: 400px;
            overflow-y: auto;
            white-space: pre-wrap;
            word-wrap: break-word;
        }

        .status-badge {
            display: inline-block;
            padding: 5px 10px;
            border-radius: 5px;
            font-size: 12px;
            font-weight: bold;
        }

        .status-running {
            background: #28a745;
            color: white;
        }

        .status-stopped {
            background: #6c757d;
            color: white;
        }

        .loading {
            display: inline-block;
            width: 20px;
            height: 20px;
            border: 3px solid #f3f3f3;
            border-top: 3px solid #667eea;
            border-radius: 50%;
            animation: spin 1s linear infinite;
            margin-left: 10px;
        }

        @keyframes spin {
            0% { transform: rotate(0deg); }
            100% { transform: rotate(360deg); }
        }
    </style>
</head>
<body>
    <div class="container">
        <div class="header">
            <h1>🔥 ChaosBlade 批量管理平台</h1>
            <p>支持CPU/内存/磁盘/网络故障注入 - 批量服务器压测工具</p>
        </div>

        <div class="content">
            <div class="panel">
                <h2>⚡ 快速操作</h2>
                <div class="btn-group">
                    <button class="btn btn-success" onclick="quickStart('cpu', 30)">启动CPU压测 (30%)</button>
                    <button class="btn btn-success" onclick="quickStart('cpu', 50)">启动CPU压测 (50%)</button>
                    <button class="btn btn-success" onclick="quickStart('mem', 40)">启动内存压测 (40%)</button>
                    <button class="btn btn-success" onclick="combinedStart(30, 40)" style="background: linear-gradient(135deg, #28a745 0%, #20c997 100%);">⭐ CPU+内存组合 (30%+40%)</button>
                    <button class="btn btn-info" onclick="checkStatus()">查看状态</button>
                    <button class="btn btn-danger" onclick="stopAll()">停止所有实验</button>
                </div>
            </div>

            <div class="panel">
                <h2>⏰ 定时任务管理</h2>
                <div class="btn-group">
                    <button class="btn btn-primary" onclick="addCronJob()">📅 添加自动检查任务</button>
                    <button class="btn btn-info" onclick="showCronJob()">👁 查看定时任务</button>
                </div>
                <p style="margin-top: 10px; color: #666; font-size: 14px;">
                    💡 提示：添加定时任务后，每小时自动检查压测状态，如果停止则自动重启（防止服务器重启后失效）
                </p>
            </div>

            <div class="panel">
                <h2>🎯 场景配置</h2>
                <div class="scenario-grid">
                    <div class="scenario-card">
                        <h3>CPU 压测</h3>
                        <div class="input-group">
                            <label>CPU使用率 (%)</label>
                            <input type="number" id="cpu-percent" value="30" min="1" max="100">
                        </div>
                        <button class="btn btn-primary" onclick="executeScenario('cpu')">执行</button>
                    </div>

                    <div class="scenario-card">
                        <h3>内存 压测</h3>
                        <div class="input-group">
                            <label>内存使用率 (%)</label>
                            <input type="number" id="mem-percent" value="50" min="1" max="100">
                        </div>
                        <button class="btn btn-primary" onclick="executeScenario('mem')">执行</button>
                    </div>

                    <div class="scenario-card">
                        <h3>磁盘填充</h3>
                        <div class="input-group">
                            <label>路径</label>
                            <input type="text" id="disk-path" value="/tmp">
                        </div>
                        <div class="input-group">
                            <label>大小 (MB)</label>
                            <input type="number" id="disk-size" value="1000">
                        </div>
                        <button class="btn btn-primary" onclick="executeScenario('disk-fill')">执行</button>
                    </div>

                    <div class="scenario-card">
                        <h3>网络延迟</h3>
                        <div class="input-group">
                            <label>延迟时间 (ms)</label>
                            <input type="number" id="network-time" value="3000">
                        </div>
                        <div class="input-group">
                            <label>网络接口</label>
                            <input type="text" id="network-interface" value="eth0">
                        </div>
                        <button class="btn btn-primary" onclick="executeScenario('network-delay')">执行</button>
                    </div>
                </div>
            </div>

            <div class="panel">
                <h2>📊 执行日志</h2>
                <div class="log-output" id="log-output">
等待执行命令...
                </div>
            </div>
        </div>
    </div>

    <script>
        function appendLog(message) {
            const logOutput = document.getElementById('log-output');
            const timestamp = new Date().toLocaleTimeString();
            logOutput.textContent += `[${timestamp}] ${message}\n`;
            logOutput.scrollTop = logOutput.scrollHeight;
        }

        async function quickStart(type, value) {
            appendLog(`启动 ${type} 压测，参数: ${value}`);

            const params = {};
            if (type === 'cpu') {
                params.cpu_percent = value;
            } else if (type === 'mem') {
                params.mem_percent = value;
            }

            try {
                const response = await fetch('/api/execute', {
                    method: 'POST',
                    headers: {'Content-Type': 'application/json'},
                    body: JSON.stringify({
                        action: 'start',
                        type: type,
                        params: params
                    })
                });

                const result = await response.json();
                if (result.success) {
                    appendLog('✓ 执行成功');
                    appendLog(result.output);
                } else {
                    appendLog('✗ 执行失败: ' + result.error);
                }
            } catch (error) {
                appendLog('✗ 请求失败: ' + error);
            }
        }

        async function executeScenario(type) {
            const params = {};

            if (type === 'cpu') {
                params.cpu_percent = document.getElementById('cpu-percent').value;
            } else if (type === 'mem') {
                params.mem_percent = document.getElementById('mem-percent').value;
            } else if (type === 'disk-fill') {
                params.path = document.getElementById('disk-path').value;
                params.size = document.getElementById('disk-size').value;
            } else if (type === 'network-delay') {
                params.time = document.getElementById('network-time').value;
                params.interface = document.getElementById('network-interface').value;
            }

            appendLog(`执行场景: ${type}, 参数: ${JSON.stringify(params)}`);

            try {
                const response = await fetch('/api/execute', {
                    method: 'POST',
                    headers: {'Content-Type': 'application/json'},
                    body: JSON.stringify({
                        action: 'start',
                        type: type,
                        params: params
                    })
                });

                const result = await response.json();
                if (result.success) {
                    appendLog('✓ 执行成功');
                    appendLog(result.output);
                } else {
                    appendLog('✗ 执行失败: ' + result.error);
                }
            } catch (error) {
                appendLog('✗ 请求失败: ' + error);
            }
        }

        async function checkStatus() {
            appendLog('查询实验状态...');

            try {
                const response = await fetch('/api/execute', {
                    method: 'POST',
                    headers: {'Content-Type': 'application/json'},
                    body: JSON.stringify({action: 'status'})
                });

                const result = await response.json();
                if (result.success) {
                    appendLog('✓ 状态查询成功');
                    appendLog(result.output);
                } else {
                    appendLog('✗ 查询失败: ' + result.error);
                }
            } catch (error) {
                appendLog('✗ 请求失败: ' + error);
            }
        }

        async function stopAll() {
            if (!confirm('确定要停止所有ChaosBlade实验吗？')) {
                return;
            }

            appendLog('停止所有实验...');

            try {
                const response = await fetch('/api/execute', {
                    method: 'POST',
                    headers: {'Content-Type': 'application/json'},
                    body: JSON.stringify({action: 'stop'})
                });

                const result = await response.json();
                if (result.success) {
                    appendLog('✓ 停止成功');
                    appendLog(result.output);
                } else {
                    appendLog('✗ 停止失败: ' + result.error);
                }
            } catch (error) {
                appendLog('✗ 请求失败: ' + error);
            }
        }

        async function combinedStart(cpuPercent, memPercent) {
            appendLog(`启动组合压测：CPU ${cpuPercent}% + 内存 ${memPercent}%`);

            try {
                const response = await fetch('/api/execute', {
                    method: 'POST',
                    headers: {'Content-Type': 'application/json'},
                    body: JSON.stringify({
                        action: 'combined',
                        params: {
                            cpu_percent: cpuPercent,
                            mem_percent: memPercent
                        }
                    })
                });

                const result = await response.json();
                if (result.success) {
                    appendLog('✓ 组合压测启动成功');
                    appendLog(result.output);
                } else {
                    appendLog('✗ 执行失败: ' + result.error);
                }
            } catch (error) {
                appendLog('✗ 请求失败: ' + error);
            }
        }

        async function addCronJob() {
            appendLog('添加定时任务...');

            try {
                const response = await fetch('/api/execute', {
                    method: 'POST',
                    headers: {'Content-Type': 'application/json'},
                    body: JSON.stringify({action: 'cron_add'})
                });

                const result = await response.json();
                if (result.success) {
                    appendLog('✓ 定时任务操作完成');
                    appendLog(result.output);
                } else {
                    appendLog('✗ 操作失败: ' + result.error);
                }
            } catch (error) {
                appendLog('✗ 请求失败: ' + error);
            }
        }

        async function showCronJob() {
            appendLog('查询定时任务...');

            try {
                const response = await fetch('/api/execute', {
                    method: 'POST',
                    headers: {'Content-Type': 'application/json'},
                    body: JSON.stringify({action: 'cron_show'})
                });

                const result = await response.json();
                if (result.success) {
                    appendLog('✓ 查询成功');
                    appendLog(result.output);
                } else {
                    appendLog('✗ 查询失败: ' + result.error);
                }
            } catch (error) {
                appendLog('✗ 请求失败: ' + error);
            }
        }
    </script>
</body>
</html>
